package study.reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class ReflectClass {
    private final static String TAG = "study.reflect.ReflectClass";

    // 创建对象
    public static void reflectNewInstance() {
        try {
            Class<?> classBook = Class.forName("study.reflect.Book");
            Book book = (Book) classBook.newInstance();
            book.setName("Java疯狂讲义");
            book.setAuthor("李刚");
            System.out.println(TAG + " reflectNewInstance book = " + book.toString());
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    // 反射私有的构造方法
    public static void reflectPrivateConstructor(){
        try {
            Class<?> classBook = Class.forName("study.reflect.Book");
            Constructor<?> declaredConstructor = classBook.getDeclaredConstructor(String.class, String.class);
            declaredConstructor.setAccessible(true);
            Book book = (Book)declaredConstructor.newInstance("Java疯狂讲义", "李刚");
            System.out.println(TAG + " reflectNewInstance book = " + book.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 反射私有属性
    public static void reflectPrivateField(){
        try {
            Class<?> classBook = Class.forName("study.reflect.Book");
            Object objectBook = classBook.newInstance();
            Field fieldTag = classBook.getDeclaredField("TAG");
            fieldTag.setAccessible(true);
            String tag = (String) fieldTag.get(objectBook);
            System.out.println(tag);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 反射私有方法
    public static void reflectPrivateMethod(){
        try {
            Class<?> classBook = Class.forName("study.reflect.Book");
            Method declaredMethod = classBook.getDeclaredMethod("declaredMethod", int.class);
            declaredMethod.setAccessible(true);
            Object objectBook = classBook.newInstance();
            String methodRes = (String) declaredMethod.invoke(objectBook, 1);
            System.out.println(methodRes);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        reflectNewInstance();
        reflectPrivateConstructor();
        reflectPrivateField();
        reflectPrivateMethod();
    }
}
